﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Lilium.Control.Reactive;
using Lilium.UI.Controls;

namespace Lilium.UI
{
    public static class UI
    {
        public static UIMonad<ILabel> Label(string label)
        {
            return new UIMonad<ILabel>(state => 
                {
                    var labelControl = state.CreateLabel();
                    labelControl.Text = label;
                    return labelControl;
                });
        }

        public static UIMonad<TResult> Select<TSource, TResult>(this UIMonad<TSource> source, Func<TSource, TResult> selector)
        {
            if (source == null) throw new ArgumentNullException("source");

            return new UIMonad<TResult>(factory => selector(source.RunUIFunc(factory)));
        }

        public static UIMonad<TResult2> SelectMany<TSource, TResult1, TResult2>(this UIMonad<TSource> ui, Func<TSource, UIMonad<TResult1>> continuation, Func<TSource, TResult1, TResult2> selector)
        {
            return new UIMonad<TResult2>(state =>
            {
                var res1 = ui.RunUIFunc(state);
                var next = continuation(res1);
                var res2 = next.RunUIFunc(state);
                return selector(res1, res2);
            });
        }

        /*
        public static UIState<ISource<Nothing>> Label<TSource>(this UIState<TSource> ui, string label)
        {
            if (ui == null) throw new ArgumentNullException("ui");
            
            var labelcontrol = ui.Viewport.AddLabel(label);
            return new UIState<ISource<Nothing>>(ui.Viewport, labelcontrol);
        }

        public static UIState<ISource<Nothing>> Label<TSource>(this UIState<TSource> ui, ISource<string> source)
        {
            if (ui == null) throw new ArgumentNullException("ui");
            if (source == null) throw new ArgumentNullException("source");

            var labelcontrol = ui.Viewport.AddLabel(null);
            source.Pushed += (string value) => labelcontrol.Text = value;
            return new UIState<ISource<Nothing>>(ui.Viewport, labelcontrol);
        }

        public static UIState<TResult> Select<TSource, TResult>(this UIState<TSource> ui, Func<TSource, TResult> selector)
        {
            return new UIState<TResult>(ui.Viewport, selector(ui.Value));
        }

        public static UIState<TResult2> SelectMany<TSource, TResult1, TResult2>(this UIState<TSource> ui, Func<TSource, UIState<TResult1>> continuation, Func<TSource, TResult1, TResult2> selector)
        {
            if (ui == null) throw new ArgumentNullException("ui");

            var intermediate = selector(ui.Value, continuation(ui.Value).Value);

            return new UIState<TResult2>(ui.Viewport, intermediate);
        }

        public static UIState<ISource<string>> TextField<TSource>(this UIState<TSource> ui)
        {
            if (ui == null) throw new ArgumentNullException("ui");

            var textField = ui.Viewport.AddTextField();

            return new UIState<ISource<string>>(ui.Viewport, textField);
        }

        public static UIState<ISource<string>> TextField<TSource>(this  UIState<TSource> ui, ISource<string> source)
        {
            if (ui == null) throw new ArgumentNullException("ui");

            var textField = ui.Viewport.AddTextField();
            source.Pushed += (string value) => textField.Text = value;
            return new UIState<ISource<string>>(ui.Viewport, textField);
        }
        */
    }
}